package com.test.myapplicatiion
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlin.random.Random

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GameApp()
        }
    }
}

@Composable
fun GameApp() {
    val gameController = remember { GameController() }
    GameScreen(gameController)
}

@Composable
fun GameScreen(gameController: GameController) {
    var cellArr by remember { mutableStateOf(gameController.getFlatCellArr()) }
    var isGameOver by remember { mutableStateOf(gameController.isGameOver) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFc1b09d))
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        if (isGameOver) {
            GameOverScreen(onRestart = {
                gameController.startGame()
                cellArr = gameController.getFlatCellArr()
                isGameOver = gameController.isGameOver
            })
        } else {
            Button(
                onClick = {
                    gameController.startGame()
                    cellArr = gameController.getFlatCellArr()
                    isGameOver = gameController.isGameOver
                },
                modifier = Modifier.padding(10.dp)
            ) {
                Text("新游戏")
            }
            LazyVerticalGrid(
                columns = GridCells.Fixed(4),
                modifier = Modifier
                    .size(300.dp)
                    .pointerInput(Unit) {
                        detectTransformGestures { _, pan, _, _ ->
                            when {
                                pan.x < -50 -> { // 向左滑动
                                    gameController.move("left")
                                    cellArr = gameController.getFlatCellArr()
                                    isGameOver = gameController.isGameOver
                                }
                                pan.x > 50 -> { // 向右滑动
                                    gameController.move("right")
                                    cellArr = gameController.getFlatCellArr()
                                    isGameOver = gameController.isGameOver
                                }
                                pan.y < -50 -> { // 向上滑动
                                    gameController.move("up")
                                    cellArr = gameController.getFlatCellArr()
                                    isGameOver = gameController.isGameOver
                                }
                                pan.y > 50 -> { // 向下滑动
                                    gameController.move("down")
                                    cellArr = gameController.getFlatCellArr()
                                    isGameOver = gameController.isGameOver
                                }
                            }
                        }
                    }
            ) {
                items(cellArr) { item ->
                    Cell(item)
                }
            }
        }
    }
}

@Composable
fun Cell(value: Int) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .padding(4.dp)
            .background(getCellBackgroundColor(value))
            .fillMaxSize()
    ) {
        Text(
            text = if (value == 0) "" else value.toString(),
            fontSize = getCellFontSize(value).sp,
            color = if (value <= 4) Color.Black else Color(0xFFfcf8f5),
            fontWeight = FontWeight.Bold
        )
    }
}

@Composable
fun GameOverScreen(onRestart: () -> Unit) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFFe4dacc))
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text("游戏结束", fontSize = 30.sp, fontWeight = FontWeight.Medium)
        Button(onClick = onRestart) {
            Text("重新开始")
        }
    }
}

fun getCellFontSize(cellValue: Int): Int {
    return when {
        cellValue < 100 -> 30
        cellValue < 1000 -> 28
        else -> 26
    }
}

fun getCellBackgroundColor(cellValue: Int): Color {
    return when (cellValue) {
        2 -> Color(0xFFeee4da)
        4 -> Color(0xFFede0c8)
        8 -> Color(0xFFf2b179)
        16 -> Color(0xFFf59563)
        32 -> Color(0xFFf67c5f)
        64 -> Color(0xFFf65e3b)
        128 -> Color(0xFFedcf72)
        256 -> Color(0xFFedcc61)
        512 -> Color(0xFFedc850)
        1024 -> Color(0xFFedc53f)
        2048 -> Color(0xFFedc22e)
        4096 -> Color(0xFF60b0c0)
        8192 -> Color(0xFF9030c0)
        else -> Color(0xFFcdc1b4)
    }
}

class GameController {
    private val gridSize = 4
    private var grid = Array(gridSize) { IntArray(gridSize) }
    var isGameOver = false
        private set

    init {
        startGame()
    }

    fun startGame() {
        grid = Array(gridSize) { IntArray(gridSize) }
        addRandomTile()
        addRandomTile()
        isGameOver = false
    }

    fun getFlatCellArr(): List<Int> {
        return grid.flatMap { it.toList() }
    }

    fun move(direction: String) {
        val prevGrid = grid.map { it.clone() }.toTypedArray()
        when (direction) {
            "left" -> moveLeft()
            "right" -> moveRight()
            "up" -> moveUp()
            "down" -> moveDown()
        }
        if (!prevGrid.contentDeepEquals(grid)) {
            addRandomTile()
            checkGameOver()
        }
    }

    private fun moveLeft() {
        for (i in 0 until gridSize) {
            grid[i] = mergeAndShift(grid[i])
        }
    }

    private fun moveRight() {
        for (i in 0 until gridSize) {
            grid[i] = mergeAndShift(grid[i].reversed().toIntArray()).reversed().toIntArray()
        }
    }

    private fun moveUp() {
        for (j in 0 until gridSize) {
            val column = IntArray(gridSize) { i -> grid[i][j] }
            val mergedColumn = mergeAndShift(column)
            for (i in 0 until gridSize) {
                grid[i][j] = mergedColumn[i]
            }
        }
    }

    private fun moveDown() {
        for (j in 0 until gridSize) {
            val column = IntArray(gridSize) { i -> grid[i][j] }
            val mergedColumn = mergeAndShift(column.reversed().toIntArray()).reversed().toIntArray()
            for (i in 0 until gridSize) {
                grid[i][j] = mergedColumn[i]
            }
        }
    }

    private fun mergeAndShift(row: IntArray): IntArray {
        val nonZeroTiles = row.filter { it != 0 }.toMutableList()
        for (i in 0 until nonZeroTiles.size - 1) {
            if (nonZeroTiles[i] == nonZeroTiles[i + 1]) {
                nonZeroTiles[i] *= 2
                nonZeroTiles.removeAt(i + 1)
            }
        }
        while (nonZeroTiles.size < gridSize) {
            nonZeroTiles.add(0)
        }
        return nonZeroTiles.toIntArray()
    }

    private fun addRandomTile() {
        val emptyCells = mutableListOf<Pair<Int, Int>>()
        for (i in 0 until gridSize) {
            for (j in 0 until gridSize) {
                if (grid[i][j] == 0) {
                    emptyCells.add(Pair(i, j))
                }
            }
        }
        if (emptyCells.isNotEmpty()) {
            val (i, j) = emptyCells.random()
            grid[i][j] = if (Random.nextFloat() < 0.9f) 2 else 4
        }
    }

    private fun checkGameOver() {
        for (i in 0 until gridSize) {
            for (j in 0 until gridSize) {
                if (grid[i][j] == 0) return
                if (i < gridSize - 1 && grid[i][j] == grid[i + 1][j]) return
                if (j < gridSize - 1 && grid[i][j] == grid[i][j + 1]) return
            }
        }
        isGameOver = true
    }
}